package edu.fsu.cs.SHPE;

import java.net.ConnectException;
import java.net.URL;
import java.util.ArrayList;

import javax.xml.parsers.SAXParser;
import javax.xml.parsers.SAXParserFactory;

import org.xml.sax.Attributes;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.DefaultHandler;

import android.util.Log;

public class SessionContainer extends ArrayList<Session> {

	private static final long serialVersionUID = 8970198305630970620L;
	private ArrayList<Session> viewableList;
	private Session tmpSession;
	private String tmpString;
	private final static String TAG = "SHPE.SessionContainer";
	
	public SessionContainer(String url) throws ConnectException{
		if(!parseXml(url))
			throw new ConnectException();
		// Adding all Sessions to Viewalbe List
		else
			setViewableSessionsByTrackId(0);
	}
	
	public void setViewableSessionsByTrackId(long id){
		if(id == 0){
			viewableList = this;
			return;
		}
		
		
		viewableList = new ArrayList<Session>();
		for(Session s : this)
			if(s.containsTrackId(id))
				viewableList.add(s);
	}
	
	public ArrayList<Session> getViewableList(){
		return viewableList;
	}
	
	public void setViewableSessionsBySpeakerId(long id){
		if(id == 0){
			viewableList = this;
			return;
		}
		
		viewableList = new ArrayList<Session>();
		for(Session s : this)
			if(s.containsSpeakerId(id))
				viewableList.add(s);
	}
	
	
	private boolean parseXml(String url){

		Log.i(TAG, "<" + url + ">");

		try {
			SAXParserFactory spf = SAXParserFactory.newInstance();
			SAXParser sp = spf.newSAXParser();
			XMLReader xr = sp.getXMLReader();

			URL sourceUrl = new URL(url);
			ConferenceXMLHandler conferenceHandler = new ConferenceXMLHandler();
			xr.setContentHandler(conferenceHandler);
			xr.parse(new InputSource(sourceUrl.openStream()));	

		} catch (Exception e) {
			return false;
		}
		
		return true;

	}

	public class ConferenceXMLHandler extends DefaultHandler {

		public void startDocument() throws SAXException {
			Log.i(TAG, "Document processing started");

			tmpSession = null;
		}


		public void endDocument() throws SAXException {
			Log.i(TAG, "Document processing finished");

			if(tmpSession != null)
				add(tmpSession);
		}


		public void startElement(String uri, String localName, String qName, Attributes attributes){
			Log.i(TAG, "in element " + localName + " qName " + qName + " uri " + uri);


			if(localName.equalsIgnoreCase("conference-session")){

				if(tmpSession != null)
					add(tmpSession);
				
				tmpSession = null;
				tmpSession = new Session();
		
				if(attributes.getValue("title") != null)
					tmpSession.setTitle(attributes.getValue("title"));

				tmpSession.setId(Long.parseLong(attributes.getValue("id")));
			}
			else if(tmpSession != null){
				
				if(localName.equalsIgnoreCase("location")){
					tmpSession.setRoom(attributes.getValue("room"));
					tmpSession.setVenueId(Long.parseLong(attributes.getValue("venue-id")));
				}
				else if(localName.equalsIgnoreCase("session-type"))
					tmpSession.setSessionTypeId(Long.parseLong(attributes.getValue("id")));
				else if(localName.equalsIgnoreCase("speaker"))
					tmpSession.addSpeakerId(Long.parseLong(attributes.getValue("id")));
				else if(localName.equalsIgnoreCase("track"))
					tmpSession.addTrackId(Long.parseLong(attributes.getValue("id")));
				else if(localName.equalsIgnoreCase("conference")){
					tmpSession.setConferenceId(Long.parseLong(attributes.getValue("id")));
					Log.i(TAG, "adding confId " + tmpSession.getConferenceId());
				}
					
			}
		}

		public void characters(char[] ch, int start, int length) throws SAXException{
			tmpString = new String(ch, start, length);
			//Log.i(TAG, "string " + tmpString);
		}

		public void endElement(String uri, String localName, String qName)
		throws SAXException {
			Log.i(TAG, "endElement " + localName);

			if(localName == null || tmpString == null || tmpSession == null)
				return;


			if(localName.equalsIgnoreCase("description"))
				tmpSession.setDescription(tmpString);
			else if(localName.equalsIgnoreCase("start-time"))
				tmpSession.setStartTime(tmpString);
			else if(localName.equalsIgnoreCase("end-time"))
				tmpSession.setEndTime(tmpString);
		}

	}
	

}
